home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / sdi / blast.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-18  |  4.4 KB  |  187 lines

  1. /***************************************  blast.c  ********************/
  2. #include <pixrect/pixrect_hs.h>
  3. #include <sunwindow/notify.h>
  4. #include "sdi.h"
  5.  
  6. /*
  7.  * Copyright 1987 by Mark Weiser.
  8.  * Permission to reproduce and use in any manner whatsoever on Suns is granted
  9.  * so long as this copyright and other identifying marks of authorship
  10.  * in the code and the game remain intact and visible.  Use of this code
  11.  * in other products is reserved to me--I'm working on Mac and IBM versions.
  12.  */
  13.  
  14. /*
  15.  * Blast-related routines are here and in intersect.c.  Also here is
  16.  * the main dispatch point for display updating called, for historical
  17.  * reasons, 'blast_timer'.
  18.  */
  19.  
  20. static Notify_value blast_timer();
  21. extern int draw_blast(), doto_missiles(), update_missile();
  22.  
  23. /*
  24.  * Start the main dispatch timer.
  25.  */
  26. init_blast()
  27. {
  28.     static char *me = (char *)&me;
  29.     struct itimerval timer;
  30.     timer.it_interval.tv_usec = 0;
  31.     timer.it_interval.tv_sec = 0;
  32.     timer.it_value.tv_usec = 1;
  33.     timer.it_value.tv_sec = 0;
  34.     notify_set_itimer_func(me, blast_timer, ITIMER_REAL, &timer, NULL);
  35. }
  36.  
  37. /*
  38.  * Construct a new blast and put it on the display list.
  39.  */
  40. start_blast(x, y, xinc, yinc, pw, circle_type)
  41. int x, y;
  42. Pixwin *pw;
  43. struct circ *circle_type;
  44. {
  45.     struct blast *bid = (struct blast *)malloc(sizeof(struct blast));
  46.     bid->pw = pw;
  47.     bid->next = NULL;
  48.     bid->circ = 0;
  49.     bid->x = x;
  50.     bid->orig_y = bid->y = y;
  51.     bid->x_inc = xinc;
  52.     bid->y_inc = yinc;
  53.     bid->num_circles = circle_type->num_circles;
  54.     bid->circles = circle_type->circles;
  55.     bid->masks = circle_type->masks;
  56.     bid->width = bid->circles[0]->pr_size.x;
  57.     update_blast_rect(bid);
  58.     add_blast(bid);
  59.     draw_blast(bid);
  60. }
  61.  
  62. #define INSCRIBING_FUDGE_FACTOR 2
  63.  
  64. /*
  65.  * Construct a square which approximates the size of the current
  66.  * blast circle.
  67.  */
  68. update_blast_rect(bid)
  69. struct blast *bid;
  70. {
  71.     register int w = bid->width / 2 - INSCRIBING_FUDGE_FACTOR;
  72.     register int h = bid->width - 2*INSCRIBING_FUDGE_FACTOR;
  73.     bid->r.r_left = bid->x - w;
  74.     bid->r.r_top = bid->y - w;
  75.     bid->r.r_width = h;
  76.     bid->r.r_height = h;
  77. }
  78.  
  79. /*
  80.  * The main dispatch routine.
  81.  * 'blast_timer' is called at fixed intervals, queries routines
  82.  * for launch, missiles, lasers, and blasts for their next update.
  83.  */
  84. static Notify_value
  85. blast_timer(me, which)
  86. int *me;
  87. int which;
  88. {
  89.     extern Panel_item foe_ground_item;
  90.     Pixwin *pw1 = citypw;
  91.     Pixwin *pw2 = launchpw;
  92.     struct itimerval timer;
  93.     struct rect r;
  94.     Event event;
  95.  
  96.     if (!running) return NOTIFY_DONE;
  97.  
  98.     if (suspended) {
  99.         suspendor(blast_timer, me, which, 1);
  100.         return NOTIFY_DONE;
  101.     }
  102.  
  103.     if (missile_count <= 0 && blast_count <= 0 &&
  104.         panel_get_value(ballistic_item) <= 0 &&
  105.         panel_get_value(foe_ground_item) <= 0)
  106.             finish_round();
  107.  
  108.     checkinput();
  109.  
  110.     timer.it_interval.tv_usec = 0;
  111.     timer.it_interval.tv_sec = 0;
  112.     timer.it_value.tv_usec = blast_delay;
  113.     timer.it_value.tv_sec = 0;
  114.     notify_set_itimer_func(pw1, blast_timer, ITIMER_REAL, &timer, NULL);
  115.  
  116.  
  117.     (void) pw_get_region_rect(pw1, &r);
  118.     pw_batch_on(pw1);
  119.     pw_lock(pw1, &r);
  120.     (void) pw_get_region_rect(pw2, &r);
  121.     pw_batch_on(pw2);
  122.     pw_lock(pw2, &r);
  123.  
  124.     if (need_a_bell != NULL) {
  125.         struct timeval tv;
  126.         tv.tv_sec = 0;
  127.         tv.tv_usec = 30000; /* this is the minimal reliable bell length */
  128.         win_bell(window_get(cityframe, WIN_FD), tv, need_a_bell);
  129.         need_a_bell = NULL;
  130.     }
  131.  
  132.     doto_missiles(update_missile);
  133.     doto_lasers();
  134.     doto_blasts(draw_blast);
  135.     doto_rocks();
  136.     doto_launch();
  137.  
  138.     pw_unlock(pw2);
  139.     pw_batch_off(pw2);
  140.     pw_unlock(pw1);
  141.     pw_batch_off(pw1);
  142.  
  143.     return NOTIFY_DONE;
  144. }
  145.  
  146. /*
  147.  * Helper routine passed into 'doto_blasts'.  Updates the
  148.  * blast circle, and frees the blast structure if done.
  149.  */
  150. draw_blast(bid)
  151. struct blast *bid;
  152. {
  153.     int old_circ =  bid->circ;
  154.  
  155.     if (bid->circ < 0 || bid->x_inc || bid->y_inc) {
  156.         /* shrinking or moving, remove old blast */
  157.         pw_rop(bid->pw, B_OFFSET_X(bid), B_OFFSET_Y(bid),
  158.             B_WIDTH(bid), B_HEIGHT(bid),
  159.             PIX_NOT(PIX_SRC) & PIX_DST,
  160.             bid->masks[ABS(bid->circ)], 0, 0);
  161.     }
  162.  
  163.  
  164.     /* Update the next blast circle.  
  165.        Positive values are growing, negative are shrinking
  166.      */
  167.     bid->circ += 1;
  168.     if (bid->circ >= bid->num_circles) {
  169.         bid->circ = -bid->num_circles +1;
  170.     }
  171.     if (bid->circ) {
  172.         /* Draw the new blast */
  173.         bid->x += bid->x_inc;
  174.         bid->y += bid->y_inc;
  175.         bid->width = bid->circles[ABS((bid)->circ)]->pr_size.x;
  176.         pw_rop(bid->pw, B_OFFSET_X(bid), B_OFFSET_Y(bid),
  177.             B_WIDTH(bid), B_HEIGHT(bid),
  178.             PIX_SRC | PIX_DST, bid->circles[ABS(bid->circ)], 0, 0);
  179.     }
  180.     if (old_circ == -1) {
  181.         remove_blast(bid);
  182.         free(bid);
  183.     } 
  184.     bid->width = bid->circles[ABS((bid)->circ)]->pr_size.x;
  185.     update_blast_rect(bid);
  186. }
  187.